package com.selfmade.transferutil;

import android.content.Context;
import android.content.SharedPreferences;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.selfmade.transferutil.app.MyApp;
import com.selfmade.transferutil.http.HttpRequest;
import com.selfmade.transferutil.model.Data;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by Selfmade on 2017/7/23/0023.
 */

public class Transition {

    private static String url = "http://172.16.69.115:8080/TransitionServer/DataProcessorServlet";
    public static final String USER_A = "UserA";
    public static final String USER_B = "UserB";
    public static final String Admin_C = "AdminC";
    private static final String PASSWORD = "123";
    private final String RECEIVER = "receiver", TRANSFER = "transfer", TIME = "time", MONEY = "money";
    private final String TRANSITION_DATA = "transition_data_";
    private final String BALANCE = "balance";
    private static Transition transition;
    public static String currentUser;
    private static int balance = -2;

    private JSONObject jsonObject;
    private HttpRequest httpRequest;
    private SharedPreferences sp, bsp;
    private SharedPreferences.Editor editor, beditor;
    private Gson gson;
    private UpdateBalance updateBalance;

    private Transition() {}

    /**
     * 根据输入的用户名和密码进行登陆陆
     * @param name 用户名
     * @param password 密码
     * @return 成功则返回实例
     */
    public static Transition login(String name, String password) {
        if (MyApp.userList.contains(name) && password.equals(PASSWORD)) {
            if (transition == null) {
                transition = new Transition();
                currentUser = name;
                transition.init();
                return transition;
            } else {
                return transition;
            }
        } else {
            return null;
        }
    }

    /**
     * 初始化成员变量，启动线程查询服务器数据
     */
    private void init () {
        httpRequest = new HttpRequest();
        jsonObject = new JSONObject();
        sp = MyApp.context.getSharedPreferences(TRANSITION_DATA + currentUser, Context.MODE_PRIVATE);
        bsp = MyApp.context.getSharedPreferences(BALANCE, Context.MODE_PRIVATE);
        editor = sp.edit();
        beditor = bsp.edit();
        gson = new Gson();
        MyApp.executor.execute(queryServer);
        if (bsp.contains("balance" + currentUser)) {
            balance = bsp.getInt("balance" + currentUser, -1);
        } else {
            beditor.putInt("balance" + currentUser, 10000);
            //beditor.putString("loginTime" + currentUser, Long.toString(System.currentTimeMillis()));
            beditor.commit();
            balance = 10000;
        }
    }

    /**
     * 查询服务器线程
     */
    private Runnable queryServer = new Runnable() {
        @Override
        public void run() {
            while (true) {
                httpRequest.httpJsonGet(url);
                delay(2);
                if (httpRequest.getGetJson() != null) {
                    JSONObject json = httpRequest.getGetJson();
                    try {
                        String dataJson = json.getString("data");
                        List<Data> dataList = new Gson().fromJson(dataJson, new TypeToken<List<Data>>(){}.getType());
                        for (Data data : dataList) {
                            if (!sp.contains(data.getTime())) {
                                editor.putString(data.getTime(), gson.toJson(data));
                                if (data.getReceiver().equals(currentUser)) {
                                    balance += data.getMoney();
                                    updateBalance.notifyUpdate(data);
                                }
                            }
                        }
                        editor.commit();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                delay(3);
            }
        }
    };

    /**
     * 转账支出
     * @param receiver 接收转账的账户
     * @param money 转出的钱数
     * @return 成功true，失败false
     */
    public boolean expend (String receiver, int money) {
        String time = Long.toString(System.currentTimeMillis());
        editor.putString(time, gson.toJson(new Data(currentUser, receiver, money, time)));
        editor.commit();
        balance = balance - money;
        beditor.putInt("balance" + currentUser, balance);
        beditor.commit();
        try {
            jsonObject.put(TRANSFER, currentUser);
            jsonObject.put(RECEIVER, receiver);
            jsonObject.put(MONEY, money);
            jsonObject.put(TIME, time);
            httpRequest.httpJsonPost(jsonObject, url);
        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 查看本用户的历史交易数据
     * @return 交易数据list
     */
    public ArrayList<Data> queryHistory() {
        ArrayList<Data> dataList = new ArrayList<>();
        Map<String, ?> dataMap = sp.getAll();
        if (!dataMap.isEmpty()) {
            for (Map.Entry<String, ?> dataJson : dataMap.entrySet()) {
                Data data = gson.fromJson((String) dataJson.getValue(), Data.class);
                if (currentUser.equals(Admin_C)) {
                    dataList.add(data);
                } else {
                    if (data.getReceiver().equals(currentUser) || data.getTransfer().equals(currentUser)) {
                        dataList.add(data);
                    }
                }
            }
        }
        Collections.sort(dataList);
        return dataList;
    }

    /**
     *  获取余额
     * @return 余额
     */
    public int getBalance() {
        return balance;
    }

    /**
     *  延时 单位：秒
     * @param seconds
     */
    private void delay(long seconds) {
        try {
            Thread.sleep(seconds * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public interface UpdateBalance {
        void notifyUpdate(Data receiveMoney);
    }

    public void setCallBack(UpdateBalance updateBalance) {
        this.updateBalance = updateBalance;
    }
}
